﻿//
// Copyright 2024 Exhunter Technology Co.Ltd2.
//

using System.Collections.Generic;
using System;
using X18.Framework.Core.Utils;

namespace X18.Framework.Core.MachineKey
{
    /// <summary>
    /// 特征码
    /// </summary>
    public class MachineKey
    {
        /// <summary>
        /// 增加特征码缓存
        /// </summary>
        private static string MachineKeyCache;
        /// <summary>
        /// 固定特征码
        /// </summary>
        private static string FixedCode = "BIO22-METUA-KIQE0-POSMD-RN65D-AMVNG";
        /// <summary>
        /// 特征码的分隔符
        /// </summary>
        public const char CodeSplitKey = '-';
        /// <summary>
        /// 高可用服务特征码的分隔符
        /// </summary>
        public const char HaSplitKey = '|';
        /// <summary>
        /// 特征码算法合集
        /// </summary>
        private static Dictionary<char, HwNoUnit> HwUnits;

        static MachineKey()
        {
            HwUnits = new Dictionary<char, HwNoUnit>();
            AddHWUnit(new HwNoWindows());
        }

        private static void AddHWUnit(HwNoUnit no)
        {
            HwUnits.Add(no.Prefix, no);
        }

        /// <summary>
        /// 获取特征码
        /// </summary>
        public static string GetKeyCode()
        {
            if (MachineKeyCache != null)
            {
                return MachineKeyCache;
            }
            // 计算特征码
            string code = "", buffer;
            foreach (var hwUnit in HwUnits)
            {
                if (hwUnit.Value.TryGet(out buffer))
                {
                    code = buffer;
                    break;
                }
            }
            if (code.IsEmpty())
            {
                return FixedCode;
            }
            MachineKeyCache = code;
            return code;
        }

        /// <summary>
        /// 效验特征码
        /// </summary>
        public static bool ValidateKeyCode(string no)
        {
            var result = no.Equals(FixedCode, StringComparison.InvariantCultureIgnoreCase);
            if (result)
            {
                return false;
            }
            if (no.IsEmpty())
            {
                return result;
            }
            var items = no.Split(HaSplitKey);
            foreach (var item in items)
            {
                char key = item[16];
                if (!HwUnits.ContainsKey(key))
                {
                    key = '0';
                }
                if (HwUnits.ContainsKey(key))
                {
                    var hwUnit = HwUnits[key];
                    if (hwUnit.Validate(no))
                    {
                        result = true;
                        break;
                    }
                }
            }
            return result;
        }

        /// <summary>
        /// 清除缓存
        /// </summary>
        public static void ClearCache()
        {
            MachineKeyCache = null;
        }
    }
}
